package com.aididi.designpatter;

/**
 * @Auther: xuzexiang
 * @Date: 2018-10-29 0029 10:39
 * @Description:    模板模式
 *  优点： 1、封装不变部分，扩展可变部分。 2、提取公共代码，便于维护。 3、行为由父类控制，子类实现。
 *  缺点：每一个不同的实现都需要一个子类来实现，导致类的个数增加，使得系统更加庞大。
 *  使用场景： 1、有多个子类共有的方法，且逻辑相同。
 *            2、重要的、复杂的方法，可以考虑作为模板方法。
 *  注意事项：为防止恶意操作，一般模板方法都加上 final 关键词
 */
public class ModelDemo {
    public static void main(String[] args) {
            //使用 Game 的模板方法 play() 来演示游戏的定义方式
        Game game ;
        game = new Cricket();
        game.playFame();
        System.out.println();
        game = new Football();
        game.playFame();
    }
}

/**
 * 创建一个抽象类，它的模板方法被设置为 final (游戏类)
 */
abstract class Game{
    //初始化游戏
    abstract void initialize();
    //开始游戏
    abstract void startGame();
    //结束游戏
    abstract void endGame();
    //打游戏的模板方法，加final避免被子类重写
    public final void playFame(){
        initialize();
        startGame();
        endGame();
    }
}

/**
 * 创建扩展了上述类的实体类 (板球类)
 */
class Cricket extends Game{
    @Override
    void initialize() {
        System.out.println("Cricket Game Initialized! Start playing.");
    }

    @Override
    void startGame() {
        System.out.println("Cricket Game Started. Enjoy the game!");
    }

    @Override
    void endGame() {
        System.out.println("Cricket Game Finished!");
    }
}
/**
 * Football (足球类)
 */
class Football extends Game{
    @Override
    void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }

    @Override
    void startGame() {
        System.out.println("Football Game Started. Enjoy the game!");
    }

    @Override
    void endGame() {
        System.out.println("Football Game Finished!");
    }
}